home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swags_z.zip / SOUND.SWG / 0022_Play VOC files on SB.pas < prev    next >
Pascal/Delphi Source File  |  1993-07-16  |  13KB  |  484 lines

  1. UNIT VOCTOOL;
  2. {* Unit - uses CT-VOICE.DRV. *}
  3. INTERFACE
  4. TYPE
  5.    VOCFileTyp = File;
  6. CONST
  7.    VOCToolVersion  = 'v1.5';
  8.    VOCBreakEnd     = 0;
  9.    VOCBreakNow     = 1;
  10. VAR
  11.    VOCStatusWord        : WORD;
  12.    VOCErrStat           : WORD;
  13.    VOCFileHeader        : STRING;
  14.    VOCFileHeaderLength  : BYTE;
  15.    VOCPaused            : BOOLEAN;
  16.    VOCDriverInstalled   : BOOLEAN;
  17.    VOCDriverVersion     : WORD;
  18.    VOCPtrToDriver       : Pointer;
  19.    OldExitProc          : Pointer;
  20. PROCEDURE PrintVOCErrMessage;
  21. FUNCTION  VOCGetBuffer(VAR VoiceBuff : Pointer; Voicefile : STRING):BOOLEAN;
  22. FUNCTION  VOCFreeBuffer(VAR VoiceBuff : Pointer):BOOLEAN;
  23. FUNCTION  VOCGetVersion:WORD;
  24. PROCEDURE VOCSetPort(PortNumber : WORD);
  25. PROCEDURE VOCSetIRQ(IRQNumber : WORD);
  26. FUNCTION  VOCInitDriver:BOOLEAN;
  27. PROCEDURE VOCDeInstallDriver;
  28. PROCEDURE VOCSetSpeaker(OnOff:BOOLEAN);
  29. PROCEDURE VOCOutput(BufferAddress : Pointer);
  30. PROCEDURE VOCOutputLoop (BufferAddress : Pointer);
  31. PROCEDURE VOCStop;
  32. PROCEDURE VOCPause;
  33. PROCEDURE VOCContinue;
  34. PROCEDURE VOCBreakLoop(BreakMode : WORD);
  35. IMPLEMENTATION
  36. USES DOS,Crt;
  37. TYPE
  38.    TypeCastType = ARRAY [0..6000] of Char;
  39. VAR
  40.    Regs : Registers;
  41. PROCEDURE PrintVOCErrMessage;
  42. {* INPUT   : None
  43.  * OUTPUT  : None
  44.  * PURPOSE : Displays SB error as text; no change to error status. }
  45. BEGIN
  46.    CASE VOCErrStat OF
  47.       100 : Write(' Driver file CT-VOICE.DRV not found ');
  48.       110 : Write(' No memory available for driver file ');
  49.       120 : Write(' False driver file ');
  50.       200 : Write(' VOC file not found ');
  51.       210 : Write(' No memory available for driver file ');
  52.       220 : Write(' File not in VOC format ');
  53.       300 : Write(' Memory allocation error occurred ');
  54.       400 : Write(' No sound blaster card found ');
  55.       410 : Write(' False port address used ');
  56.       420 : Write(' False interrupt used ');
  57.       500 : Write(' No loop in process ');
  58.       510 : Write(' No sample for output ');
  59.       520 : Write(' No sample available ');
  60.       END;
  61.    END;
  62.  
  63. FUNCTION Exists (Filename : STRING):BOOLEAN;
  64. {* INPUT   : Filename as string
  65.  * OUTPUT  : TRUE if file is available, FALSE if not
  66.  * PURPOSE : Checks for availability of file then returns Boolean exp. }
  67. VAR
  68.    F : File;
  69. BEGIN
  70.    Assign(F,Filename);
  71. {$I-}
  72.    Reset(F);
  73.    Close(F);
  74. {$I+}
  75.    Exists := (IoResult = 0) AND (Filename <> '');
  76.    END;
  77. PROCEDURE AllocateMem (VAR Pt : Pointer; Size : LongInt);
  78. {* INPUT   : Buffer variable as pointer, buffer size as LongInt
  79.  * OUTPUT  : Pointer to buffer in variable or NIL
  80.  * PURPOSE : Reserves as many bytes as Size allows, then moves pointer in
  81.              the Pt variable. If not enough memory is available, Pt = NIL. }
  82. VAR
  83.    SizeIntern : WORD;
  84. BEGIN
  85.    Inc(Size,15);
  86.    SizeIntern := (Size shr 4);
  87.    Regs.AH := $48;
  88.    Regs.BX := SizeIntern;
  89.    MsDos(Regs);
  90.    IF (Regs.BX <> SizeIntern) THEN Pt := NIL
  91.    ELSE Pt := Ptr(Regs.AX,0);
  92.    END;
  93. FUNCTION  CheckFreeMem (VAR VoiceBuff : Pointer; VoiceSize : LongInt):BOOLEAN;
  94. {* INPUT   : Buffer variable as pointer, size as LongInt
  95.  * OUTPUT  : Pointer to buffer, TRUE/FALSE, after AllocateMem
  96.  * PURPOSE : Checks for sufficient memory to store a VOC file. }
  97. BEGIN
  98.    AllocateMem(VoiceBuff,VoiceSize);
  99.    CheckFreeMem := VoiceBuff <> NIL;
  100.    END;
  101. FUNCTION  VOCGetBuffer (VAR VoiceBuff : Pointer; Voicefile : STRING):BOOLEAN;
  102. {* INPUT   : Buffer variable as pointer, file name as string
  103.  * OUTPUT  : Pointer to buffer with VOC data, TRUE/FALSE
  104.  * PURPOSE : Loads a file into memory and returns TRUE if file loaded
  105.              successfully, and FALSE if not. }
  106. VAR
  107.    SampleSize : LongInt;
  108.    FPresent   : BOOLEAN;
  109.    VFile      : VOCFileTyp;
  110.    Segs       : WORD;
  111.    Read       : WORD;
  112. BEGIN
  113.    FPresent := Exists(VoiceFile);
  114. { VOC file not found }
  115.    IF Not(FPresent) THEN BEGIN
  116.       VOCGetBuffer := FALSE;
  117.       VOCErrStat   := 200;
  118.       EXIT
  119.       END;
  120.    Assign(VFile,Voicefile);
  121.    Reset(VFile,1);
  122.    SampleSize := Filesize(VFile);
  123.    AllocateMem(VoiceBuff,SampleSize);
  124. { Insufficient memory for the VOC file }
  125.    IF (VoiceBuff = NIL) THEN BEGIN
  126.       Close(VFile);
  127.       VOCGetBuffer := FALSE;
  128.       VOCErrStat   := 210;
  129.       EXIT;
  130.       END;
  131.    Segs := 0;
  132.    REPEAT
  133.       Blockread(VFile,Ptr(seg(VoiceBuff^)+4096*Segs,Ofs(VoiceBuff^))^,$FFFF,Read
  134. );
  135.       Inc(Segs);
  136.       UNTIL Read = 0;
  137.    Close(VFile);
  138. { File not in VOC format }
  139.    IF (TypeCastType(VoiceBuff^)[0]<>'C') OR
  140.       (TypeCastType(VoiceBuff^)[1]<>'r') THEN BEGIN
  141.       VOCGetBuffer := FALSE;
  142.       VOCErrStat := 220;
  143.       EXIT;
  144.       END;
  145. { Load successful }
  146.    VOCGetBuffer := TRUE;
  147.    VOCErrStat   := 0;
  148. { Read header length from file }
  149.    VOCFileHeaderLength := Ord(TypeCastType(VoiceBuff^)[20]);
  150.    END;
  151. FUNCTION VOCFreeBuffer (VAR VoiceBuff : Pointer):BOOLEAN;
  152. {* INPUT   : Buffer pointer
  153.  * OUTPUT  : None
  154.  * PURPOSE : Frees memory allocated for VOC data. }
  155. BEGIN
  156.    Regs.AH := $49;
  157.    Regs.ES := seg(VoiceBuff^);
  158.    MsDos(Regs);
  159.    VOCFreeBuffer := TRUE;
  160.    IF (Regs.AX = 7) OR (Regs.AX = 9) THEN BEGIN
  161.       VOCFreeBuffer := FALSE;
  162.       VOCErrStat := 300
  163.       END;
  164.    END;
  165. FUNCTION VOCGetVersion:WORD;
  166. {* INPUT   : None
  167.  * OUTPUT  : Driver version number
  168.  * PURPOSE : Returns driver version number. }
  169. VAR
  170.    VDummy : WORD;
  171. BEGIN
  172.    ASM
  173.       MOV       BX,0
  174.       CALL      VOCPtrToDriver
  175.       MOV       VDummy, AX
  176.       END;
  177.    VOCGetVersion := VDummy;
  178.    END;
  179.  
  180. PROCEDURE VOCSetPort(PortNumber : WORD);
  181. {* INPUT   : Port address number
  182.  * OUTPUT  : None
  183.  * PURPOSE : Specifies port address before initialization. }
  184. BEGIN
  185.    ASM
  186.       MOV    BX,1
  187.       MOV    AX,PortNumber
  188.       CALL   VOCPtrToDriver
  189.       END;
  190.    END;
  191. PROCEDURE VOCSetIRQ(IRQNumber : WORD);
  192. {* INPUT   : Interrupt number
  193.  * OUTPUT  : None
  194.  * PURPOSE : Specifies interrupt number before initialization.}
  195. BEGIN
  196.    ASM
  197.       MOV    BX,2
  198.       MOV    AX,IRQNumber
  199.       CALL   VOCPtrToDriver
  200.       END;
  201.    END;
  202. FUNCTION  VOCInitDriver: BOOLEAN;
  203. {* INPUT   : None
  204.  * OUTPUT  : Error message number, and initialization result
  205.  * PURPOSE : Initializes driver software. }
  206. VAR
  207.    Out, VSeg, VOfs : WORD;
  208.    F   : File;
  209.    Drivername,
  210.    Pdir        : DirStr;
  211.    Pnam        : NameStr;
  212.    Pext        : ExtStr;
  213. BEGIN
  214. { Search path for CT-VOICE.DRV driver }
  215.    Pdir := ParamStr(0);
  216.    Fsplit(ParamStr(0),Pdir,Pnam,Pext);
  217.    Drivername := Pdir+'CT-VOICE.DRV';
  218.    VOCInitDriver := TRUE;
  219. { Driver file not found }
  220.    IF Not Exists(Drivername) THEN BEGIN
  221.       VOCInitDriver := FALSE;
  222.       VOCErrStat    := 100;
  223.       EXIT;
  224.       END;
  225. { Load driver }
  226.    Assign(F,Drivername);
  227.    Reset(F,1);
  228.    AllocateMem(VOCPtrToDriver,Filesize(F));
  229. { No memory can be allocated for the driver }
  230.    IF VOCPtrToDriver = NIL THEN BEGIN
  231.       VOCInitDriver := FALSE;
  232.       VOCErrStat    := 110;
  233.       EXIT;
  234.       END;
  235.    Blockread(F,VOCPtrToDriver^,Filesize(F));
  236.    Close(F);
  237. { Driver file doesn't begin with "CT" - false driver }
  238.    IF (TypeCastType(VOCPtrToDriver^)[3]<>'C') OR
  239.       (TypeCastType(VOCPtrToDriver^)[4]<>'T') THEN BEGIN
  240.          VOCInitDriver := FALSE;
  241.          VOCErrStat    := 120;
  242.          EXIT;
  243.          END;
  244. { Get version number and pass to global variable }
  245.    VOCDriverVersion := VOCGetVersion;
  246. { Start driver }
  247.    Vseg := Seg(VOCStatusWord);
  248.    VOfs := Ofs(VOCStatusWord);
  249.    ASM
  250.       MOV       BX,3
  251.       CALL      VOCPtrToDriver
  252.       MOV       Out,AX
  253.       MOV       BX,5
  254.       MOV       ES,VSeg
  255.       MOV       DI,VOfs
  256.       CALL      VOCPtrToDriver
  257.       END;
  258. { No Sound Blaster card found }
  259.    IF Out = 1 THEN BEGIN
  260.       VOCInitDriver := FALSE;
  261.       VOCErrStat    := 400;
  262.       EXIT;
  263.       END;
  264. { False port address used }
  265.    IF Out = 2 THEN BEGIN
  266.       VOCInitDriver := FALSE;
  267.       VOCErrStat    := 410;
  268.       EXIT;
  269.       END;
  270. { False interrupt used }
  271.    IF Out = 3 THEN BEGIN
  272.       VOCInitDriver := FALSE;
  273.       VOCErrStat    := 420;
  274.       EXIT;
  275.       END;
  276.    END;
  277. PROCEDURE VOCDeInstallDriver;
  278. {* INPUT   : None
  279.  * OUTPUT  : None
  280.  * PURPOSE : Disables driver and releases memory. }
  281. VAR
  282.    Check : BOOLEAN;
  283. BEGIN
  284.    IF VOCDriverInstalled THEN
  285.    ASM
  286.       MOV       BX,9
  287.       CALL      VOCPtrToDriver
  288.       END;
  289.    Check := VOCFreeBuffer(VOCPtrToDriver);
  290.    END;
  291. PROCEDURE VOCSetSpeaker(OnOff:BOOLEAN);
  292. {* INPUT   : TRUE=Speaker on, FALSE=Speaker off
  293.  * OUTPUT  : None
  294.  * PURPOSE : Sound Blaster output status. }
  295. VAR
  296.    Switch : BYTE;
  297. BEGIN
  298.    Switch := Ord(OnOff) AND $01;
  299.    ASM
  300.       MOV       BX,4
  301.       MOV       AL,Switch
  302.       CALL      VOCPtrToDriver
  303.       END;
  304.    END;
  305. PROCEDURE VOCOutput (BufferAddress : Pointer);
  306. {* INPUT   : Pointer to sample data
  307.  * OUTPUT  : None
  308.  * PURPOSE : Plays sample. }
  309. VAR
  310.    VSeg, VOfs : WORD;
  311. BEGIN
  312.    VOCSetSpeaker(TRUE);
  313.    VSeg := Seg(BufferAddress^);
  314.    VOfs := Ofs(BufferAddress^)+VOCFileHeaderLength;
  315.    ASM
  316.       MOV       BX,6
  317.       MOV       ES,VSeg
  318.       MOV       DI,VOfs
  319.       CALL      VOCPtrToDriver
  320.       END;
  321.    END;
  322. PROCEDURE VOCOutputLoop (BufferAddress : Pointer);
  323. {*    Different from VOCOutput :
  324.  *    Speaker does not switch on with every sample output, so a
  325.  *    crackling noise may occur with some Sound Blaster cards. }
  326. VAR
  327.    VSeg, VOfs : WORD;
  328. BEGIN
  329.    VSeg := Seg(BufferAddress^);
  330.    VOfs := Ofs(BufferAddress^)+VOCFileHeaderLength;
  331.    ASM
  332.       MOV       BX,6
  333.       MOV       ES,VSeg
  334.       MOV       DI,VOfs
  335.       CALL      VOCPtrToDriver
  336.       END;
  337.    END;
  338. PROCEDURE VOCStop;
  339. {* INPUT   : None
  340.  * OUTPUT  : None
  341.  * PURPOSE : Stops a sample. }
  342. BEGIN
  343.    ASM
  344.       MOV       BX,8
  345.       CALL      VOCPtrToDriver
  346.       END;
  347.    END;
  348. PROCEDURE VOCPause;
  349. {* INPUT   : None
  350.  * OUTPUT  : None
  351.  * PURPOSE : Pauses a sample. }
  352. VAR
  353.    Switch : WORD;
  354. BEGIN
  355.    VOCPaused := TRUE;
  356.    ASM
  357.       MOV       BX,10
  358.       CALL      VOCPtrToDriver
  359.       MOV       Switch,AX
  360.       END;
  361.    IF (Switch = 1) THEN BEGIN
  362.       VOCPaused := FALSE;
  363.       VOCErrStat := 510;
  364.       END;
  365.    END;
  366. PROCEDURE VOCContinue;
  367. {* INPUT   : None
  368.  * OUTPUT  : None
  369.  * PURPOSE : Continues a paused sample. }
  370. VAR
  371.    Switch : WORD;
  372. BEGIN
  373.    ASM
  374.       MOV       BX,11
  375.       CALL      VOCPtrToDriver
  376.       MOV       Switch,AX
  377.       END;
  378.    IF (Switch = 1) THEN BEGIN
  379.       VOCPaused := FALSE;
  380.       VOCErrStat := 520;
  381.       END;
  382.    END;
  383. PROCEDURE VOCBreakLoop(BreakMode : WORD);
  384. {* INPUT   : Break mode
  385.  * OUTPUT  : None
  386.  * PURPOSE : Breaks a sample loop. }
  387. BEGIN
  388.    ASM
  389.       MOV       BX,12
  390.       MOV       AX,BreakMode
  391.       CALL      VOCPtrToDriver
  392.       MOV       BreakMode,AX
  393.       END;
  394.    IF (BreakMode = 1) THEN VOCErrStat := 500;
  395.    END;
  396. {$F+}
  397. PROCEDURE VoiceToolsExitProc;
  398. {$F-}
  399. {* INPUT   : None
  400.  * OUTPUT  : None
  401.  * PURPOSE : De-installs voice driver. }
  402. BEGIN
  403.    VOCDeInstallDriver;
  404.    ExitProc := OldExitProc;
  405.    END;
  406. BEGIN
  407. {* The following statements execute automatically, as soon as the
  408.  * unit is linked to a program, and the program starts. }
  409. { Replaces old ExitProc with new one from Tool unit }
  410.    OldExitProc := ExitProc;
  411.    ExitProc := @VoiceToolsExitProc;
  412. { Initialize values }
  413.    VOCStatusWord := 0;
  414.    VOCErrStat    := 0;
  415.    VOCPaused     := FALSE;
  416.    VOCFileHeaderLength := $1A;
  417.    VOCFileHeader :=
  418.       'Creative Voice File'+#$1A+#$1A+#$00+#$0A+#$01+#$29+#$11+#$01;
  419. {* After installation, VOCDriverInstalled contains either TRUE or FALSE. }
  420.    VOCDriverInstalled := VOCInitDriver;
  421.    END.
  422.  
  423.  
  424. {    -----------------------    DEMO PROGRAM  --------------------------}
  425.  
  426. PROGRAM VToolTest;
  427. {* VTTEST.PAS - uses VOCTOOL.TPU *}
  428.  
  429. {$M 16000,0,50000}
  430. USES Crt,Voctool;
  431. VAR
  432.    Sound : Pointer;
  433.    Check : BOOLEAN;
  434.    Ch    : CHAR;
  435. PROCEDURE TextNumError;
  436. {* INPUT   : None; data comes from the VOCErrStat global variable
  437.  * OUTPUT  : None
  438.  * PURPOSE : Displays SB error on the screen as text, including the
  439.              error number. Program then ends at the error level
  440.              corresponding to the error number. }
  441. BEGIN
  442.    Write(' Error #',VOCErrStat:3,' =');
  443.    PrintVOCErrMessage;
  444.    WriteLn;
  445.    HALT(VOCErrStat);
  446.    END;
  447.  
  448. BEGIN
  449.   ClrScr;
  450.  
  451. { Driver not initialized }
  452.   IF Not(VOCDriverInstalled) THEN TextNumError;
  453. { Loads DEMO.VOC file into memory }
  454.   Check := VOCGetBuffer(Sound,'\SBPRO\MMPLAY\SBP.VOC');
  455. { VOC file could not be loaded }
  456.   IF Not(Check) THEN TextNumError;
  457. { Main loop }
  458.   Write('CT-Voice Driver Version : ');
  459.   WriteLn(Hi(VOCDriverVersion),'.',Lo(VOCDriverVersion));
  460.   WriteLn('(S)ingle play or (M)ultiple play?');
  461.   Write('Press a key : '); Ch := ReadKey;WriteLn;WriteLn;
  462.   CASE UpCase(Ch) OF
  463.    'S' : BEGIN
  464.             Write('Press a key to stop the sound...');
  465.             VOCOutput(Sound);
  466.             REPEAT UNTIL KeyPressed OR (VOCStatusWord = 0);
  467.             IF KeyPressed THEN VOCStop;
  468.             END;
  469.    'M' : BEGIN
  470.             Ch := #0;
  471.             Write('Press <ESC> to cancel...');
  472.             REPEAT
  473.                VOCOutputLoop(Sound);
  474.                REPEAT UNTIL KeyPressed OR (VOCStatusWord = 0);
  475.                IF KeyPressed THEN Ch := ReadKey;
  476.                UNTIL Ch = #27;
  477.             VOCStop;
  478.             END;
  479.    END;
  480. { Free VOC file memory }
  481.   Check := VOCFreeBuffer(Sound);
  482.   IF Not(Check) THEN TextNumError;
  483.   END.
  484.